﻿using System;
using System.Collections.Generic;
using Calimbra.Runtime.Contracts;

namespace Calimbra.Runtime.Functions
{
    public class Join<T> : IJoin<T>
    {
        private IEnumerable<T> message1;
        private bool message1Present;
        private IEnumerable<T> message2;
        private bool message2Present;
        public event Action<IEnumerable<T>> Output;
        private readonly bool autoReset;

        public Join() : this(false) {}
        protected Join(bool autoReset)
        {
            this.autoReset = autoReset;
        }

        public void Input1(IEnumerable<T> message)
        {
            message1 = message;
            message1Present = true;
            if (message2Present)
            {
                OutputResult();
            }
        }

        public void Input2(IEnumerable<T> message)
        {
            message2 = message;
            message2Present = true;
            if (message1Present)
            {
                OutputResult();
            }
        }

        private void OutputResult()
        {
            var result = new List<T>();
            result.AddRange(message1);
            result.AddRange(message2);
          
            if (autoReset)
                ClearMessagePresence();
            Output(result);
        }

        protected void ClearMessagePresence()
        {
            message1Present = false;
            message2Present = false;
        }

        public class AutoResetJoin<T> : Join<T>
        {
            public AutoResetJoin() : base(true)
            {
            }
        }


        public class ManualResetJoin<T> : Join<T>
        {
            public void Reset<T>(T ignore)
            {
                Reset();
            }
            public void Reset()
            {
                ClearMessagePresence();
            }
        }
    }
}
